{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "4c3bfe99",
   "metadata": {},
   "source": [
    "# 在 单-三重态量子比特系统中，采用不同脉冲数实现单量子比特任意门的计算结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "26986f0b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "进度: 11/32  error_min: 8.73232940834523e-06 iter_num: 630\n",
      "mean of iter_num: 630.0\n",
      "\n",
      " mean of error is： 8.73232940834523e-06\n",
      "\n",
      "error_min_list:\n",
      " [8.73232940834523e-06]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import sys\n",
    "from numpy import kron\n",
    "from mindquantum import *\n",
    "from scipy.linalg import expm\n",
    "import mindspore as ms\n",
    "from mindspore import ops\n",
    "ms.context.set_context(mode=ms.context.PYNATIVE_MODE, device_target=\"CPU\")\n",
    "from mindspore.nn import Adam, TrainOneStepCell\n",
    "from mindspore import Tensor\n",
    "from mindspore.common.parameter import Parameter\n",
    "from mindspore.common.initializer import initializer  \n",
    "ms.set_seed(1)\n",
    "np.random.seed(1)\n",
    "\n",
    "train_x = np.load('./src/1_qubit_train_x.npy', allow_pickle=True)\n",
    "eval_x = np.load('./src/1_qubit_eval_x.npy', allow_pickle=True)\n",
    "train_y = np.load('./src/1_qubit_train_y.npy', allow_pickle=True)\n",
    "eval_y = np.load('./src/1_qubit_eval_y.npy', allow_pickle=True)\n",
    "u_mats = np.load('./src/1_qubit_u.npy', allow_pickle=True)\n",
    "\n",
    "s_x = X.matrix()\n",
    "s_z = Z.matrix()\n",
    "one = I.matrix()\n",
    "dt = np.pi/2\n",
    "\n",
    "def _matrix_0(coeff):\n",
    "    return expm(-1j*(coeff*s_z+s_x)*dt)\n",
    "\n",
    "def _diff_matrix_0(coeff):\n",
    "    return -1j*_matrix_0(coeff)@(s_z*dt)\n",
    "\n",
    "gate_0 = gene_univ_parameterized_gate('gete_0', _matrix_0, _diff_matrix_0)\n",
    "\n",
    "circ = Circuit()\n",
    "circ += gate_0('00').on(0)\n",
    "circ += gate_0('01').on(0)\n",
    "circ += gate_0('02').on(0)\n",
    "circ += gate_0('03').on(0)\n",
    "circ += gate_0('04').on(0)\n",
    "circ += gate_0('05').on(0)\n",
    "circ += gate_0('06').on(0)\n",
    "circ += gate_0('07').on(0)\n",
    "circ += gate_0('08').on(0)\n",
    "circ += gate_0('09').on(0)\n",
    "\n",
    "circ += gate_0('10').on(0)\n",
    "# circ += gate_0('11').on(0)\n",
    "# circ += gate_0('12').on(0)\n",
    "# circ += gate_0('13').on(0)\n",
    "# circ += gate_0('14').on(0)\n",
    "# circ += gate_0('15').on(0)\n",
    "\n",
    "ham = Hamiltonian(QubitOperator('')) \n",
    "sim = Simulator('projectq', circ.n_qubits)\n",
    "sim_left = Simulator('projectq',circ.n_qubits)\n",
    "grad_ops = sim.get_expectation_with_grad(ham,\n",
    "                                         circ,\n",
    "                                         circ_left=Circuit(),\n",
    "                                         simulator_left=sim_left,\n",
    "                                         ansatz_params_name=circ.params_name)\n",
    "\n",
    "\n",
    "error_min_list = [] \n",
    "m_list = []\n",
    "lr = 0.1\n",
    "for i in [10]: #range(len(u_mats)):\n",
    "    Quantum_net = MQLayer(grad_ops)\n",
    "    opti = Adam(Quantum_net.trainable_params(), learning_rate=lr)  \n",
    "    net = TrainOneStepCell(Quantum_net, opti)\n",
    "    error_min = 1\n",
    "    for j in range(len(train_x)):\n",
    "        net(Tensor(train_x[j]), Tensor(train_y[i,j]))\n",
    "        params = abs(Quantum_net.weight.asnumpy())\n",
    "        final_state = []\n",
    "        for k in range(100): # 100 个测试点\n",
    "            sim.reset()\n",
    "            sim.set_qs(eval_x[k])\n",
    "            sim.apply_circuit(circ, params)\n",
    "            final_state.append(sim.get_qs())\n",
    "        error = 1-np.real(np.min([np.abs(np.vdot(bra, ket)) for bra, ket in zip(np.array(final_state), eval_y[i])]))\n",
    "        error_min = min(error, error_min)\n",
    "        if error_min < 1e-5:\n",
    "            break\n",
    "    error_min_list.append(error_min)\n",
    "    m_list.append(j)\n",
    "    print(f\"进度: {i+1}/{len(u_mats)} \", 'error_min:', error_min, 'iter_num:', j)\n",
    "    \n",
    "print('mean of iter_num:', np.mean(m_list))\n",
    "print('\\n mean of error is：', np.mean(error_min_list))\n",
    "print('\\nerror_min_list:\\n', error_min_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "710492b7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "进度: 6/32  error_min: 3.7591990563745625e-06 iter_num: 292\n",
      "mean of iter_num: 292.0\n",
      "\n",
      " mean of error is： 3.7591990563745625e-06\n",
      "\n",
      "error_min_list:\n",
      " [3.7591990563745625e-06]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import sys\n",
    "from numpy import kron\n",
    "from mindquantum import *\n",
    "from scipy.linalg import expm\n",
    "import mindspore as ms\n",
    "from mindspore import ops\n",
    "ms.context.set_context(mode=ms.context.PYNATIVE_MODE, device_target=\"CPU\")\n",
    "from mindspore.nn import Adam, TrainOneStepCell\n",
    "from mindspore import Tensor\n",
    "from mindspore.common.parameter import Parameter\n",
    "from mindspore.common.initializer import initializer  \n",
    "ms.set_seed(1)\n",
    "np.random.seed(1)\n",
    "\n",
    "train_x = np.load('./src/1_qubit_train_x.npy', allow_pickle=True)\n",
    "eval_x = np.load('./src/1_qubit_eval_x.npy', allow_pickle=True)\n",
    "train_y = np.load('./src/1_qubit_train_y.npy', allow_pickle=True)\n",
    "eval_y = np.load('./src/1_qubit_eval_y.npy', allow_pickle=True)\n",
    "u_mats = np.load('./src/1_qubit_u.npy', allow_pickle=True)\n",
    "\n",
    "s_x = X.matrix()\n",
    "s_z = Z.matrix()\n",
    "one = I.matrix()\n",
    "dt = np.pi/2\n",
    "\n",
    "def _matrix_0(coeff):\n",
    "    return expm(-1j*(coeff*s_z+s_x)*dt)\n",
    "\n",
    "def _diff_matrix_0(coeff):\n",
    "    return -1j*_matrix_0(coeff)@(s_z*dt)\n",
    "\n",
    "gate_0 = gene_univ_parameterized_gate('gete_0', _matrix_0, _diff_matrix_0)\n",
    "\n",
    "circ = Circuit()\n",
    "circ += gate_0('00').on(0)\n",
    "circ += gate_0('01').on(0)\n",
    "circ += gate_0('02').on(0)\n",
    "circ += gate_0('03').on(0)\n",
    "circ += gate_0('04').on(0)\n",
    "circ += gate_0('05').on(0)\n",
    "circ += gate_0('06').on(0)\n",
    "circ += gate_0('07').on(0)\n",
    "circ += gate_0('08').on(0)\n",
    "circ += gate_0('09').on(0)\n",
    "\n",
    "circ += gate_0('10').on(0)\n",
    "# circ += gate_0('11').on(0)\n",
    "# circ += gate_0('12').on(0)\n",
    "# circ += gate_0('13').on(0)\n",
    "# circ += gate_0('14').on(0)\n",
    "# circ += gate_0('15').on(0)\n",
    "\n",
    "ham = Hamiltonian(QubitOperator('')) \n",
    "sim = Simulator('projectq', circ.n_qubits)\n",
    "sim_left = Simulator('projectq',circ.n_qubits)\n",
    "grad_ops = sim.get_expectation_with_grad(ham,\n",
    "                                         circ,\n",
    "                                         circ_left=Circuit(),\n",
    "                                         simulator_left=sim_left,\n",
    "                                         ansatz_params_name=circ.params_name)\n",
    "\n",
    "\n",
    "error_min_list = [] \n",
    "m_list = []\n",
    "lr = 0.1\n",
    "for i in [5]: #range(len(u_mats)):\n",
    "    Quantum_net = MQLayer(grad_ops)\n",
    "    opti = Adam(Quantum_net.trainable_params(), learning_rate=lr)  \n",
    "    net = TrainOneStepCell(Quantum_net, opti)\n",
    "    error_min = 1\n",
    "    for j in range(len(train_x)):\n",
    "        net(Tensor(train_x[j]), Tensor(train_y[i,j]))\n",
    "        params = abs(Quantum_net.weight.asnumpy())\n",
    "        final_state = []\n",
    "        for k in range(100): # 100 个测试点\n",
    "            sim.reset()\n",
    "            sim.set_qs(eval_x[k])\n",
    "            sim.apply_circuit(circ, params)\n",
    "            final_state.append(sim.get_qs())\n",
    "        error = 1-np.real(np.min([np.abs(np.vdot(bra, ket)) for bra, ket in zip(np.array(final_state), eval_y[i])]))\n",
    "        error_min = min(error, error_min)\n",
    "        if error_min < 1e-5:\n",
    "            break\n",
    "    error_min_list.append(error_min)\n",
    "    m_list.append(j)\n",
    "    print(f\"进度: {i+1}/{len(u_mats)} \", 'error_min:', error_min, 'iter_num:', j)\n",
    "    \n",
    "print('mean of iter_num:', np.mean(m_list))\n",
    "print('\\n mean of error is：', np.mean(error_min_list))\n",
    "print('\\nerror_min_list:\\n', error_min_list)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
